const {validate} = require("schema-utils");
const path = require("path")
const globby = require("globby")
const schema = require("./schemaCopy.json")
const fs = require('fs')
const {promisify} = require('util')
const webpack = require("webpack")
const {RawSource} = webpack.sources

const readFile = promisify(fs.readFile)

class copyWebpackplugin{
    constructor({options = {}}){
        //验证Options是否符合规范
        validate(schema,options,{
            name:'copyWebpackplugin'
        })
        this.options = options
    }

    apply(compiler){
        //初始化compilation
        compiler.hooks.thisCompilation.tap('copyWebpackplugin',(compilation)=>{
            //添加资源
            compilation.hooks.additionalAssets.tabAsync('copyWebpackplugin',async (callbback)=>{
                //目的：将from中的资源复制到to中,输出出去
                const {from,ignore} = this.options
                const to = this.options.to ? this.options.to : '.'
            
                //content 就是webpack配置
                //运行指令目录
                const context = compiler.options.context //等价于process.cwd()
                //将输入路劲变成绝对路劲
                const absoluteFrom = path.isAbsolute(from) ? from : path.resolve(context,from)

                //1.过滤掉ignore的文件
                //globby(要处理的文件夹,options)
                const paths = await globby(absoluteFrom,{ignore})
                console.log(paths) //所有要加载的文件路径

                //2.获取paths下所有的资源
                const files = await Promise.all(
                    paths.map(async (absolutePath)=>{
                        //读取文件
                        const data = await readFile(absolutePath)
                        //basename得到最后的文件名称
                        const relativePath = path.basename(absolutePath)
                        //和to属性结合
                        //没有to --> reset.css
                        //有to --> css/reset.css
                        const filename = path.join(to,relativePath)

                        return{
                            //文件内容
                            data,
                            //文件名称
                            filename
                        }
                    })
                )

                //3.生成webpack格式的资源
                const assets = files.map(file=>{
                    const source = new RawSource(file.data)
                    return{
                        source,
                        filename:file.filename
                    }
                })

                //4.添加到compilation，再生成出去
                assets.forEach(assets=>{
                    compilation.emitAsset(assets.source,assets.filename)
                })
            })
        })
    }
}

module.exports = copyWebpackplugin